package com.kk.xhr.model.service.impl;

import com.kk.xhr.common.pojo.BinaryEnum;
import com.kk.xhr.model.assembler.DepartmentStructKit;
import com.kk.xhr.model.dao.DepartmentDynamicSqlSupport;
import com.kk.xhr.model.dao.DepartmentMapper;
import com.kk.xhr.model.dao.custom.DepartmentCustomMapper;
import com.kk.xhr.model.dto.DepartmentDTO;
import com.kk.xhr.model.dto.DepartmentTreeDTO;
import com.kk.xhr.model.entity.Department;
import com.kk.xhr.model.service.IDepartmentService;
import lombok.RequiredArgsConstructor;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;

import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import static com.kk.xhr.common.RedisConstant.DEPARTMENT_CACHE;
import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo;
import static org.mybatis.dynamic.sql.SqlBuilder.isIn;

/**
 * 部门服务接口实现
 *
 * @author kkmystery
 * @version 1.0 2021/3/4
 * @since 1.0.0
 */
@Repository
@RequiredArgsConstructor
@CacheConfig(cacheNames = DEPARTMENT_CACHE)
public class DepartmentServiceImpl implements IDepartmentService {
    private final DepartmentMapper departmentMapper;
    private final DepartmentCustomMapper departmentCustomMapper;
    private final DepartmentStructKit instance = DepartmentStructKit.INSTANCE;

    /**
     * {@inheritDoc}
     */
    @Override
    public DepartmentTreeDTO query(Long id) {
        return departmentCustomMapper.query(id);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @Cacheable(key = "#id")
    public Optional<DepartmentDTO> queryById(Long id) {
        return departmentMapper.selectOne(dsl -> dsl
            .where(DepartmentDynamicSqlSupport.id, isEqualTo(id))
            .and(DepartmentDynamicSqlSupport.status, isEqualTo(BinaryEnum.TRUE.getValue())))
            .map(instance::toDto);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public long add(DepartmentDTO dto) {
        Department entity = instance.toEntity(dto);
        departmentMapper.insertSelective(entity);
        return entity.getId();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @CacheEvict(key = "#p0.id")
    public boolean modify(DepartmentDTO dto) {
        if (null == dto.getId()) {
            return false;
        }
        return 1 == departmentMapper.updateByPrimaryKeySelective(instance.toEntity(dto));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @CacheEvict(allEntries = true)
    public boolean modifyStatus(Collection<Long> ids, BinaryEnum status) {
        if (null == status || CollectionUtils.isEmpty(ids)) {
            return false;
        }
        return 1 == departmentMapper.delete(dsl -> dsl.where(DepartmentDynamicSqlSupport.id, isIn(ids)));
    }

    @Override
    public boolean checkByUserId(Long userId) {
        return departmentMapper.selectOne(dsl -> dsl
            .where(DepartmentDynamicSqlSupport.userId, isEqualTo(userId))
            .and(DepartmentDynamicSqlSupport.status, isEqualTo(BinaryEnum.TRUE.getValue()))
            .limit(1))
            .isPresent();
    }

    @Override
    public List<Long> queryByUserId(Long userId) {
        return departmentMapper.select(dsl -> dsl
            .where(DepartmentDynamicSqlSupport.userId, isEqualTo(userId))
            .and(DepartmentDynamicSqlSupport.status, isEqualTo(BinaryEnum.TRUE.getValue())))
            .stream()
            .map(Department::getId)
            .collect(Collectors.toList());
    }
}
